import { EcsComponent, RegComponentType, RegObjProp } from "./EcsComponent";
import { EcsEntityGroup } from "./EcsEntityGroup";
import { EcsEntity } from "./EcsEntity";
import { EcsSystem } from "./EcsSystem";
import { EcsWorld } from "./EcsWorld";

const entityCount = 1

class CommonSystem extends EcsSystem<TestWorld> {
    public group2: EcsEntityGroup = null;
    constructor(world: TestWorld, defaltGroupComps: (new () => EcsComponent)[]) {
        super(world, defaltGroupComps)
        this.group2 = world.getGroupByClz(Comp.B);
    }
    public update(): void {
        if (this.defaultGroup.entities.length >= 100) {
            console.time("removeEntity")
            this.defaultGroup.forEach((entity) => {
                entity.component(Comp.A).value = 11
                entity.component(Comp.A).pos.x = 11

                this.world.removeEntity(entity.id)
            })

            console.timeEnd("removeEntity")
            console.log( Object.keys(this.world.entities).length)
        }

        this.defaultGroup.forEach((entity) => {
            // console.log("defaultGroup", entity.id)

        })

        this.group2.forEach((entity) => {
            // console.log("group2", entity.id)

        })


        // console.time("addComponent")
        // let count=0
        // for (let index = this.group2.entities.length - 1; index >= 0; index--) {
        //     const element = this.group2.entities[index];
        //     element.addComponent(Comp.A)
        //     count++
        // }
        // console.timeEnd("addComponent")
        // log("addComponent",count)


        for (let index = 0; index < entityCount; index++) {
            const entity = this.world.addEntityWithComps([
                Comp.B,
                Comp.A
            ])
            console.log("addComponent", entity.component(Comp.A).pos)
        }




    }

}

namespace Comp {
    @RegComponentType()
    export class A extends EcsComponent {
        public value: number = 0;
        @RegObjProp()
        public pos = { x: 0, y: 0 }
    }

    @RegComponentType()
    export class B extends EcsComponent {
        public value: number = 2;
    }

    @RegComponentType()
    export class C extends EcsComponent {
        public value: number = 0;
    }
    @RegComponentType()
    export class D extends EcsComponent {
        public value: number = 0;
    }
    @RegComponentType()
    export class E extends EcsComponent {
        public value: number = 0;
    }
    @RegComponentType()
    export class F extends EcsComponent {
        public value: number = 0;
    }
    @RegComponentType()
    export class G extends EcsComponent {
        public value: number = 0;
    }
}

class TestWorld extends EcsWorld {
    afterEntityCreated(entity: EcsEntity) {
    }
    beforeEntityRemove(entity: EcsEntity) {
    }
    protected initSingletons(): void {
    }
    protected initEntityTypes(): void {
    }
    protected initSystems(): void {
        this.addSystem(new CommonSystem(this, [Comp.A, Comp.B]))
    }
    constructor() {
        super();
    }

    init() {
        this.enable = true
        // console.time("addEntityWithComps")
        // for (let index = 0; index < entityCount; index++) {
        //     this.addEntityWithComps(
        //         [
        //             Comp.A,
        //             Comp.B,
        //             Comp.C,
        //             Comp.D,
        //             Comp.E,
        //             Comp.F,
        //             Comp.G,
        //         ]
        //     )
        // }
        // console.timeEnd("addEntityWithComps")

        console.time("addEntitybyPool")
        const pool = this.regEntityPool([
            Comp.A,
            Comp.B,
            Comp.C,
            Comp.D,
            Comp.E,
            Comp.F,
            Comp.G,

        ])
        for (let index = 0; index < entityCount; index++) {
            this.addEntityByGroupId(pool.groupId)
        }
        console.timeEnd("addEntitybyPool")
    }
}

// const world = new TestWorld()
// world.init()

// const interval = 1000 / 60
// setInterval(() => {
//     world.update(interval)
// }, interval)